/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package ca.usherbrooke.model.entity;

import java.util.ArrayList;
import java.util.List;

import org.newdawn.slick.geom.Rectangle;

import ca.usherbrooke.model.entity.behaviours.EquipmentBehaviour;
import ca.usherbrooke.model.entity.behaviours.FightBehaviour;
import ca.usherbrooke.model.equipment.EquipmentModel;
import ca.usherbrooke.model.equipment.ProtectionModel;
import ca.usherbrooke.model.equipment.WeaponModel;
import ca.usherbrooke.model.feature.GroundModel;
import ca.usherbrooke.tools.position.Vector2D;

/**
 * this class is a use to transfer any IEntityModel, it is a lightweight version
 * but most of the action are disable
 * 
 * @author Cody Stoutenburg
 * 
 */
public class EntityDTO implements IEntityGame {
	private static final long serialVersionUID = 1L;

	private final Long guid;
	private final String name;
	private final Rectangle size;
	private final Vector2D position;
	private final Vector2D positionCenter;

	private final Float range;
	private final Integer attackModifier;
	private final Integer defense;

	private final Rectangle viewingArea;

	private final Boolean isJumping;
	private final Integer jumpReloadTime;
	private final Integer remaningJumpReload;
	private final Integer maxJumpDuration;
	private final Integer currentJumpDuration;

	private final Boolean isDead;
	private final Integer maxHp;
	private final Integer currentHp;

	private final Integer capacity;
	private final Integer maxCapacity;

	private final Float maxSpeed;
	private final Vector2D currentSpeed;
	private final Vector2D realSpeed;
	private final Vector2D targetPosition;
	private final Vector2D lastTargetPosition;

	private final Integer remainAttackTime;

	private final List<EquipmentModel> allEquipment;

	private final List<ProtectionModel> allProtection;
	private final WeaponModel currentWeapon;

	public EntityDTO(IEntityModel model) {
		guid = model.getGuid();
		name = model.getName();
		size = model.getSize();
		position = new Vector2D(0f, 0f);
		positionCenter = new Vector2D(0f, 0f);
		this.updatePosition();

		range = model.getRange();
		attackModifier = model.getAttackModifier();
		defense = model.getDefense();

		allProtection = model.getCurrentProtection();
		currentWeapon = model.getCurrentWeapon();

		viewingArea = model.getViewingArea();

		isJumping = model.isJumping();
		jumpReloadTime = model.getJumpReloadTime();
		remaningJumpReload = model.getRemaningJumpReload();
		maxJumpDuration = model.getMaxJumpDuration();
		currentJumpDuration = model.getCurrentJumpDuration();

		maxHp = model.getMaxHP();
		currentHp = model.getCurrentHP();

		maxSpeed = model.getMaxSpeed();
		currentSpeed = model.getCurrentSpeed();
		realSpeed = model.getRealSpeed();
		targetPosition = model.getTargetPosition();
		lastTargetPosition = model.getLastTargetReach();
		allEquipment = model.getEquipments();

		remainAttackTime = model.getRemainingAttackTime();

		isDead = model.isDead();

		capacity = model.getCapacity();
		maxCapacity = model.getMaxCapacity();
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public Vector2D getPosition() {
		return position.clone();
	}

	@Override
	public Vector2D getCenterPosition() {
		return positionCenter.clone();
	}

	@Override
	public Rectangle getSize() {
		return size;
	}

	@Override
	public Long getGuid() {
		return guid;
	}

	@Override
	public Float getRange() {
		return range;
	}

	@Override
	public Integer getAttackModifier() {
		return attackModifier;
	}

	@Override
	public Integer getDefense() {
		return defense;
	}

	@Override
	public Rectangle getViewingArea() {
		return viewingArea;
	}

	@Override
	public Boolean isJumping() {
		return isJumping;
	}

	@Override
	public Integer getJumpReloadTime() {
		return jumpReloadTime;
	}

	@Override
	public Integer getRemaningJumpReload() {
		return remaningJumpReload;
	}

	@Override
	public Integer getMaxJumpDuration() {
		return maxJumpDuration;
	}

	@Override
	public Integer getCurrentJumpDuration() {
		return currentJumpDuration;
	}

	@Override
	public Integer getMaxHP() {
		return maxHp;
	}

	@Override
	public Integer getCurrentHP() {
		return currentHp;
	}

	@Override
	public Float getMaxSpeed() {
		return maxSpeed;
	}

	@Override
	public Vector2D getCurrentSpeed() {
		return currentSpeed;
	}

	@Override
	public Vector2D getRealSpeed() {
		return realSpeed;
	}

	@Override
	public Vector2D getTargetPosition() {
		return targetPosition;
	}

	@Override
	public Integer getRemainingAttackTime() {
		return remainAttackTime;
	}

	@Override
	public Boolean canPickUpEquipment(EquipmentModel newEquipement) {
		return EquipmentBehaviour.canPickUpEquipment(this, newEquipement);
	}

	@Override
	public List<EquipmentModel> getEquipments() {
		return allEquipment;
	}

	@Override
	public Vector2D getLastTargetReach() {
		return lastTargetPosition;
	}

	@Override
	public Integer getCapacity() {
		return capacity;
	}

	@Override
	public Integer getMaxCapacity() {
		return maxCapacity;
	}

	@Override
	public Boolean isDead() {
		return isDead;
	}

	private void updatePosition() {
		position.setX(size.getX());
		position.setY(size.getY());

		positionCenter.setX(size.getCenterX());
		positionCenter.setY(size.getCenterY());
	}

	@Override
	public void setPosition(Vector2D position) {
		size.setLocation(position.getX(), position.getY());
		updatePosition();
	}

	@Override
	public WeaponModel getCurrentWeapon() {
		return currentWeapon;
	}

	@Override
	public List<ProtectionModel> getCurrentProtection() {
		return allProtection;
	}

	@Override
	public Boolean canWearProtection(ProtectionModel newProtection) {
		return FightBehaviour.canWearProtection(this, newProtection);
	}

	@Override
	public Boolean doesWearProtection(ProtectionModel protection) {
		return FightBehaviour.doesWearProtection(this, protection);
	}

	@Override
	public Boolean canTakeWeapon(WeaponModel weapon) {
		return FightBehaviour.canTakeWeapon(this, weapon);
	}

	@Override
	public List<WeaponModel> getWeaponsInEquipments() {
		List<WeaponModel> result = new ArrayList<WeaponModel>();
		for (EquipmentModel equipment : allEquipment) {
			if (equipment instanceof WeaponModel) {
				result.add((WeaponModel) equipment);
			}
		}
		return result;
	}

	@Override
	public List<ProtectionModel> getProtectionsInEquipments() {
		List<ProtectionModel> result = new ArrayList<ProtectionModel>();
		for (EquipmentModel equipment : allEquipment) {
			if (equipment instanceof ProtectionModel) {
				result.add((ProtectionModel) equipment);
			}
		}
		return result;
	}

	// Unimplemented setters because this object is a transfert object
	@Override
	public void setWalkOn(GroundModel ground) {
	}

	@Override
	public void doDamage(Integer amount) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void doJump() {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void setSpeed(Vector2D newSpeed) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void setTargetPosition(Vector2D upperLeftCorner) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void doAttack(IEntityModel defender) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void doLogic(int delta) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void doMove(int delta) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void pickUp(EquipmentModel newEquipement) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public Boolean putDown(EquipmentModel oldEquipement) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public GroundModel getWalkOn() {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void takeProtection(ProtectionModel protection) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void putDownProtection(ProtectionModel protection) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void takeWeapon(WeaponModel weapon) {
		throw new UnsupportedOperationException("Method not implemented");
	}

	@Override
	public void putDownWeapon() {
		throw new UnsupportedOperationException("Method not implemented");
	}
}
